package com.luoran.bartalks.action;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.beetl.sql.core.engine.PageQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.luoran.bartalks.core.UserContext;
import com.luoran.bartalks.core.ext.Pageable;
import com.luoran.bartalks.entity.BaseInfo;
import com.luoran.bartalks.entity.biz.BtCodingRule;
import com.luoran.bartalks.service.IBtCodingRuleService;
import com.luoran.bartalks.utils.DateFormatUtils;
import com.luoran.bartalks.utils.EnumBillType;
import com.luoran.bartalks.utils.UUID;

@Controller
@RequestMapping("/codingRule")
public class BtCodingRuleAction implements Pageable {

	@Autowired
	private IBtCodingRuleService codingRuleService;

	private static final Logger log = LoggerFactory.getLogger(BtCodingRuleAction.class);

	// 分页展示
	@RequestMapping
	public String show() {
		return "/systemManage/codingRule-list";
	}

	// 停用启用
	@RequestMapping("/start")
	@ResponseBody
	public JSONObject startCodingRule(BtCodingRule codingRule) {
		// 接收前台传递过来的id和状态.更新.
		JSONObject result = new JSONObject();
		// 传递过来的status =1 停用 此时需要判断 是否还有其他的同一类型的规则启用,如果没有,提示需要必须有一条规则启用
		// 同一公司.同一单据类型的编码规则只会有一个是处于启用状态。
		if (1 == codingRule.getRuleStatus()) {
			result.put("msg", "该单据类型必须有一条规则处于启用状态!");
			result.put("flag", true);
			return result;
		} else {
			// 传递过来status = 0 启用 此时需要关闭该公司已启用的同一类型的规则
			String billType = codingRule.getBillType();
			codingRuleService.closeStartedRule(billType, UserContext.get().getCompanyId());
			// 更新状态
			int count = codingRuleService.updateCodingRule(codingRule);

			if (count != 0) {
				result.put("flag", true);
				result.put("msg", "操作成功");
				return result;
			}
			result.put("flag", false);
			result.put("msg", "操作失败");
			return result;
		}
	}

	// 新增
	@RequestMapping("/addCodingRule")
	@ResponseBody
	public JSONObject addCodingRule(BtCodingRule codingRule) {

		codingRule.setCompanyId(UserContext.get().getCompanyId());// 公司ID
		codingRule.setCreateTime(new Date());// 创建时间
		codingRule.setRuleStatus(1);// 新增默认停用

		String uuid = codingRuleService.addCodingRule(codingRule);
		JSONObject obj = new JSONObject();
		if (uuid != null) {
			obj.put("flag", true);
			obj.put("msg", "操作成功,请手动启用");
			return obj;
		} else {
			obj.put("flag", false);
			obj.put("msg", "操作失败,请重试!");
			return obj;
		}

	}

	// 获取对应记录信息
	@RequestMapping("/showItem/{id}")
	@ResponseBody
	public BtCodingRule getCodingRule(@PathVariable("id") String id) {
		return codingRuleService.getCodingRule(id);
	}

	// 智能一键开启
	@RequestMapping("/smartCreate")
	@ResponseBody
	public JSONObject smartCreate() {
		JSONObject res = new JSONObject();
		String companyId = UserContext.get().getCompanyId();
		// 先查询
		List<BtCodingRule> allCodingRule = codingRuleService.getAllByCompanyId(companyId);
		List<BtCodingRule> insertList = new ArrayList<BtCodingRule>();
		List<BtCodingRule> updataList = new ArrayList<BtCodingRule>();
		if (allCodingRule == null || allCodingRule.size() == 0) {
			// 编码生成规则对象
			for (EnumBillType e : EnumBillType.values()) {
				BtCodingRule codingRule = CodingRuleFactory(e, companyId);
				insertList.add(codingRule);
			}
		} else {
			for (EnumBillType e : EnumBillType.values()) {
				List<BtCodingRule> filterByEnum = allCodingRule.stream()
						.filter(item -> e.getName().equals(item.getBillType())).collect(Collectors.toList());
				if (filterByEnum.size() > 1) {
					filterByEnum.stream().forEach(item -> item.setTimeStamp(
							(int) (DateFormatUtils.dateCompare(item.getCreateTime(), item.getUpdateTime()).getTime()
									/ 1000)));
					List<BtCodingRule> sortedList = filterByEnum.stream()
							.sorted((Comparator.comparing(BtCodingRule::getTimeStamp).reversed()))
							.collect(Collectors.toList());
					for (int i = 0; i < sortedList.size(); i++) {
						if (i == 0) {
							if(sortedList.get(i).getRuleStatus() == 0) {
								continue;
							}else {
								sortedList.get(i).setRuleStatus(0);
								updataList.add(sortedList.get(i));
							}
						} else {
							if (sortedList.get(i).getRuleStatus() == 0) {
								sortedList.get(i).setRuleStatus(1);
								updataList.add(sortedList.get(i));
							}
						}
					}

				} else if (filterByEnum.size() == 1) {
					BtCodingRule btCodingRule = filterByEnum.get(0);
					if (btCodingRule.getRuleStatus() == 1) {
						btCodingRule.setRuleStatus(0);
						btCodingRule.setUpdateTime(new Date());
						updataList.add(btCodingRule);
					}
				} else {
					insertList.add(CodingRuleFactory(e, companyId));
				}
			}
		}
		if ((insertList == null || insertList.size() == 0) && (updataList == null || updataList.size() == 0)) {
			res.put("state", true);
			res.put("msg", "无需改动!");
		} else {
			boolean boole = codingRuleService.smartCreate(insertList, updataList);
			if (boole == false) {
				res.put("state", false);
				res.put("msg", "操作失败!");
				return res;
			} else {
				res.put("state", true);
				res.put("msg", "操作成功!");
			}
		}
		return res;
	}

	public BtCodingRule CodingRuleFactory(EnumBillType e, String companyId) {
		BtCodingRule codingRule = new BtCodingRule();
		codingRule.setId(UUID.get());
		codingRule.setCompanyId(companyId);// 公司ID
		codingRule.setSequenceLength(5);// 序列长度
		codingRule.setSequenceBeginValue(0);// 起步值
		codingRule.setStepLengthValue(1);// 步长值
		codingRule.setCreateTime(new Date());// 创建日期
		codingRule.setRuleStatus(0);// 状态
		codingRule.setRuleDesc("初始化编码生成规则");

		switch (e) {
		case AREA:
			codingRule.setBillType(EnumBillType.AREA.getName());// 区域
			codingRule.setCodingPrefix("QY-");// 区域编码前缀
			break;
		case POSITION:
			codingRule.setBillType(EnumBillType.POSITION.getName());// 位置
			codingRule.setCodingPrefix("WZ-");// 位置编码前缀
			break;
		case CONTAINER:
			codingRule.setBillType(EnumBillType.CONTAINER.getName());// 容器
			codingRule.setCodingPrefix("RQ-");// 容器编码前缀
			break;
		case CONTAINERTEMPLATE:
			codingRule.setBillType(EnumBillType.CONTAINERTEMPLATE.getName());// 容器模板
			codingRule.setCodingPrefix("RQMB-");// 容器模板编码前缀
			break;
		case TRANSPORTMETHOD:
			codingRule.setBillType(EnumBillType.TRANSPORTMETHOD.getName());// 运输方式
			codingRule.setCodingPrefix("YSFS-");// 区域编码前缀
			break;
		case PLANTEMPLATE:
			codingRule.setBillType(EnumBillType.PLANTEMPLATE.getName());// 计划模板
			codingRule.setCodingPrefix("JHMB-");// 计划模板编码前缀
			break;
		case PROJECT:
			codingRule.setBillType(EnumBillType.PROJECT.getName());// 项目
			codingRule.setCodingPrefix("XM-");// 项目编码前缀
			break;
		case PLAN:
			codingRule.setBillType(EnumBillType.PLAN.getName());// 计划
			codingRule.setCodingPrefix("JH-");// 区域编码前缀
			break;
		case PACKINGLIST:
			codingRule.setBillType(EnumBillType.PACKINGLIST.getName());// 箱单
			codingRule.setCodingPrefix("QY-");// 区域编码前缀
			break;
		default:
			break;
		}
		return codingRule;

	}

	// 编辑更新
	@RequestMapping("/updateCodingRule")
	@ResponseBody
	public JSONObject updateCodingRule(BtCodingRule codingRule) {
		log.info("编辑编码规则>>");

		JSONObject obj = new JSONObject();
		// 同样需要获取当前公司 启动的规则,如果有.停用.没有则不作操作.
		String billType = codingRule.getBillType();
		// 根据单据类型,启用状态,公司id..同一公司,同一单据类型只有一个编码规则启用
		log.info("停用该单据类型已启用的编码规则>>");
		codingRuleService.closeStartedRule(billType, UserContext.get().getCompanyId());

		// 需要把当前序列值重置为起步值
		codingRule.setSequenceValue(codingRule.getSequenceBeginValue());
		// 保存修改信息并开启当前规则.
		codingRule.setUpdateTime(new Date());// 设置更新时间
		codingRule.setRuleStatus(0);// 更新立即启用.
		codingRule.setCompanyId(UserContext.get().getCompanyId());// 设置公司
		// 根据主键更新
		int count = codingRuleService.editCodingRule(codingRule);
		if (count != 0) {
			obj.put("flag", true);
			obj.put("msg", "操作成功!");
			return obj;
		}
		obj.put("flag", false);
		obj.put("msg", "操作失败!");
		return obj;
	}

	@Override
	public PageQuery<? extends BaseInfo> getQueryList(PageQuery<? extends BaseInfo> pageQuery) {
		@SuppressWarnings("unchecked")
		Map<String, String> params = (HashMap<String, String>) pageQuery.getParas();
		params.put("companyId", UserContext.get().getCompanyId());
		pageQuery.setParas(params);
		if (StringUtils.isEmpty(pageQuery.getOrderBy())) {
			pageQuery.setOrderBy("bc.bill_type desc , bc.create_time desc");
		}
		return codingRuleService.getQueryList(pageQuery);
	}

}
